/*
 * leerSector.c
 *
 *  Created on: 09/09/2011
 *      Author: Power Rangers Turbo C
 */
#define SECTOR_LENGTH 512
#define SECTORES_POR_PAGINA 8//paginas de 4096 bytes
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>//uintN_t N bits, http://linux.die.net/man/3/uint32_t
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include "operacionesSectores.h"

//este leer sector es temporal, despues va a pedir la pagina que va a estar en una cache probablemente.

char *leerSector(uint32_t numeroSector,char * contenedor, uint32_t descriptorArchivo) {

	char *datosExtraidos;
	uint32_t numeroPagina;
	uint32_t desplazamientoEnPagina;
	uint32_t i;

	// Caclculo nro de pagina.
	numeroPagina = sectorAPagina(numeroSector);

	//Calculo el desplazamiento sobre esa pagina.
	desplazamientoEnPagina = (numeroSector % SECTORES_POR_PAGINA)
			* SECTOR_LENGTH; // % es residuo de division

	//Pongo en un puntero la pagina del archivo disco obtenida con mmap(). Lo hago con PROT_READ para q solo se pueda leer
	datosExtraidos = mmap(0, getpagesize(), PROT_READ, MAP_SHARED,
			descriptorArchivo, numeroPagina * getpagesize()); //(caddr_) 0 es para que el SO decida la ubicacion en memoria que va a tener
	if (datosExtraidos ==  MAP_FAILED){
		return " MAP_FAILED";
	}
//printf("no fallo mmap 1\n");
	/*posix_madvise(datosExtraidos, getpagesize(), int advice);
	 * aca solo le tengo que avisa por socket al planificador que esta pagina se uso
	 * y con un algoritmo de cache ira viendo que advise darle
	 *
	 * POSIX_MADV_WILLNEED
	 * POSIX_MADV_DONTNEED
	 * fijandose en las colas si la pagina se va a necesitar ,etc*/

	//Copio la parte de la pagina que quiero al contenedor del sector.
	for (i = desplazamientoEnPagina;
			i < desplazamientoEnPagina + SECTOR_LENGTH; i++) {
		contenedor[i - desplazamientoEnPagina] = datosExtraidos[i];
	}
//printf("no fallo mmap 2\n\n");
	//Libero la memoria usada en el mmap()
	munmap(datosExtraidos, getpagesize());

	return contenedor;
}

void escribirSector(uint32_t numeroSector, uint8_t *contenedorAGrabar,
		uint32_t descriptorArchivo) {
	uint32_t numeroPagina;
	uint32_t desplazamientoEnPagina;
	char *datosExtraidos;
	uint32_t i;

	// Caclculo nro de pagina.
	numeroPagina = sectorAPagina(numeroSector);

	//Calculo el desplazamiento sobre esa pagina.
	desplazamientoEnPagina = (numeroSector % SECTORES_POR_PAGINA)
			* SECTOR_LENGTH; // % es residuo de division
	//Pongo en un puntero la pagina del archivo disco obtenida con mmap().  lo hago con PROT_WRITE para escribir.
	datosExtraidos = mmap(0, getpagesize(), PROT_WRITE, MAP_SHARED,
			descriptorArchivo, numeroPagina * getpagesize()); //(caddr_) 0 es para que el SO decida la ubicacion en memoria que va a tener

	//Copio el sector a la pagina mapeada en memoria.
	for (i = desplazamientoEnPagina;
			i < desplazamientoEnPagina + SECTOR_LENGTH; i++) {
		 datosExtraidos[i]=contenedorAGrabar[i - desplazamientoEnPagina];
	}
	//desmapeo para asegura q se escriba el archivo, pors ahi mas adelante uso msync() q hace lo mismo pero sin desmapear
	munmap(datosExtraidos, getpagesize());
}

uint32_t sectorAPagina(uint32_t sector) {
	return (sector / SECTORES_POR_PAGINA);
}

